﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BobcatUtility;

namespace BobcatMultiTouch
{
    /// <summary>
    /// This form lets you manage the config for the available multi-touch sources.
    /// It shows an icon bar with one icon for each source. If you choose a source, 
    /// details for the source are shown on the right-hand side of the screen. You
    /// can set whether the source is active and any custom configuration there is
    /// for that source.
    /// </summary>
    public partial class MultiTouchConfig : Form
    {
        #region Public methods

        /// <summary>
        /// Constructor.
        /// </summary>
        public MultiTouchConfig()
        {
            InitializeComponent();
        }

        #endregion

        #region Private functions

        /// <summary>
        /// Called when the form is loaded. We show the available sources. 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MultiTouchConfig_Load(object sender, EventArgs e)
        {
            // We show the available sources in the icon-strip...
            foreach (MultiTouchInputManager.SourceInfo sourceInfo in m_MTIM.getSourceInfos())
            {
                IMultiTouchSource source = sourceInfo.Source;
                IconControl control = new IconControl();
                control.setIcon(source.getIcon(), source.getSourceName(), source.getSourceName());  // We use the source name as the display name and the unique ID.
                ctrlIconStrip.addControl(control);
            }

            // We and register for click events and select the first source...
            ctrlIconStrip.SelectionChangedEvent += onSelectionChangedEvent;
            ctrlIconStrip.setSelectedIndex(0);
        }

        /// <summary>
        /// Called when the selected source changes
        /// </summary>
        private void onSelectionChangedEvent(object sender, ControlStripControl.Args e)
        {
            IconControl control = (IconControl)e.Control;

            // We find the source from the ID...
            m_SelectedSourceInfo = m_MTIM.getSourceInfo(control.ID);
            
            // We show the source details...
            showGeneralProperties();
            showSpecificProperties();


        }

        /// <summary>
        /// Shows the general properties that are common to all sources.
        /// </summary>
        private void showGeneralProperties()
        {
            // Is a valid source selected?
            if (m_SelectedSourceInfo == null)
            {
                return;
            }

            // We show the general properties (i.e the name and active flag)...
            lblSourceName.Text = m_SelectedSourceInfo.Source.getSourceName();
            chkActive.Checked = m_SelectedSourceInfo.Active;
        }

        /// <summary>
        /// Shows specific properties for the selected source.
        /// </summary>
        private void showSpecificProperties()
        {
            // We clear any previos cusom config...
            if (m_CustomConfigControl != null)
            {
                gbSpecificProperties.Controls.Remove(m_CustomConfigControl);
            }

            // Is a valid source selected?
            if (m_SelectedSourceInfo == null)
            {
                return;
            }

            // Is there any custom config for this source? The specific properties are 
            // managed by user-controls specified by the souces themselves. We see if
            // there is one for this source...
            m_CustomConfigControl = m_SelectedSourceInfo.Source.getConfigControl();
            if (m_CustomConfigControl != null)
            {
                lblNoCustomConfig.Visible = false;
                m_CustomConfigControl.Location = new Point(CONFIG_CONTROL_OFFSET, CONFIG_CONTROL_TOP_OFFSET);
                m_CustomConfigControl.Size = new Size(gbSpecificProperties.Width - CONFIG_CONTROL_OFFSET * 2, gbSpecificProperties.Height - CONFIG_CONTROL_OFFSET - CONFIG_CONTROL_TOP_OFFSET);
                m_CustomConfigControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
                gbSpecificProperties.Controls.Add(m_CustomConfigControl);

                // We gray out the config if the source is not active...
                m_CustomConfigControl.Enabled = chkActive.Checked;
            }
            else
            {
                lblNoCustomConfig.Visible = true;
            }
        }

        /// <summary>
        /// Called if the 'active' checkbox changes state.
        /// </summary>
        private void chkActive_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                Cursor = Cursors.WaitCursor;

                // We activate or deactivate the source...
                string strSourceName = m_SelectedSourceInfo.Source.getSourceName();
                m_MTIM.activateSource(strSourceName, chkActive.Checked);

                // We re-show the custom config as it may have changed...
                showSpecificProperties();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                // We reset the cursor...
                Cursor = Cursors.Default;

                // We show whether the source is active. Even if we are activating the
                // source, the activation may have failed. So here we show the state that
                // it's actually ended up in...
                chkActive.Checked = m_SelectedSourceInfo.Active;
            }
        }

        /// <summary>
        /// Called when the OK button, Esc or Enter is pressed.
        /// </summary>
        private void cmdOK_Click(object sender, EventArgs e)
        {
            // As data is updated as changes are make, we just close the form...
            Close();
        }

        #endregion

        #region Private data

        private const int CONFIG_CONTROL_OFFSET = 11;
        private const int CONFIG_CONTROL_TOP_OFFSET = 20;

        // The source info for the selected source...
        private MultiTouchInputManager.SourceInfo m_SelectedSourceInfo = null;
        private MultiTouchInputManager m_MTIM = MultiTouchInputManager.getInstance();
        UserControl m_CustomConfigControl = null;

        #endregion

    }
}
